package com.ruoyi.swla2.service.impl;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.swla2.constant.GeoType;
import com.ruoyi.swla2.domain.PgFieldTableInfo;
import com.ruoyi.swla2.domain.PgRowInfo;
import com.ruoyi.swla2.domain.PgTableInfo;
import com.ruoyi.swla2.mapper.PgEditMapper;
import com.ruoyi.swla2.service.IPgEditService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class PgEditServiceImpl implements IPgEditService {

    @Autowired
    PgEditMapper pgEditMapper;

    /**
     * 连接PostGIS本地数据库并获取表名
     *
     * @return 是否创建成功
     */
    @Override
    public AjaxResult getTableInfo() {
        List<PgTableInfo> pgTableInfoList = new ArrayList<>();
        List<Map<String, Object>> tableNames = pgEditMapper.getGeomTable();
        if (tableNames.isEmpty()) {
            return AjaxResult.error("获取失败！");
        }
        for (Map<String, Object> item : tableNames) {
            if (item.get("name").toString().contains("planet")) continue;
            PgTableInfo pgTableInfo = new PgTableInfo();
            int number = pgEditMapper.getTableNumber(item.get("name").toString());
            if (number == 0) continue;
            String type = pgEditMapper.getGeomType(item.get("name").toString(), item.get("column").toString());
            pgTableInfo.setName(item.get("name").toString());
            pgTableInfo.setType(GeoType.getTypeGeom(type));
            pgTableInfo.setGeom(item.get("column").toString());
            pgTableInfo.setNumber(number + "");
            pgTableInfoList.add(pgTableInfo);
        }
        return AjaxResult.success("获取成功！", pgTableInfoList);
    }

    /**
     * 连接PostGIS本地数据库并获取表名
     *
     * @return 是否创建成功
     */
    @Override
    public AjaxResult getTableData(PgFieldTableInfo pgFieldTableInfo) {
        List<Map<String, Object>> listData = pgEditMapper.getTableData(pgFieldTableInfo.getTableName(), pgFieldTableInfo.getGeom(), pgFieldTableInfo.getPageNum(), pgFieldTableInfo.getPageSize());
        return AjaxResult.success("获取成功！", listData);
    }

    /**
     * 连接PostGIS数据库并查询GIS表数据
     *
     * @return 是否创建成功
     */
    @Override
    public AjaxResult findGisTableData(PgFieldTableInfo pgFieldTableInfo) {
        List<Map<String, Object>> listData = pgEditMapper.findGisTableData(pgFieldTableInfo.getTableName(), pgFieldTableInfo.getGeom(), pgFieldTableInfo.getFields(), pgFieldTableInfo.getFieldValues(), pgFieldTableInfo.getPageNum(), pgFieldTableInfo.getPageSize());
        return AjaxResult.success("获取成功！", listData);
    }

    /**
     * 连接PostGIS数据库并查询GIS表数据
     *
     * @return 是否创建成功
     */
    @Override
    public AjaxResult findNormalTableData(PgFieldTableInfo pgFieldTableInfo) {
        List<Map<String, Object>> listData = pgEditMapper.findNormalTableData(pgFieldTableInfo.getTableName(), pgFieldTableInfo.getFields(), pgFieldTableInfo.getFieldValues(), pgFieldTableInfo.getPageNum(), pgFieldTableInfo.getPageSize());
        return AjaxResult.success("获取成功！", listData);
    }

    /**
     * 添加数据
     *
     * @return 是否成功
     */
    @Override
    public AjaxResult addTableData(PgRowInfo pgRowInfo) {
        boolean add = pgEditMapper.insertTableData(pgRowInfo.getTableName(), pgRowInfo.getNewRow(), pgRowInfo.getFields());
        if (add) {
            return AjaxResult.success("数据添加成功！");
        } else {
            return AjaxResult.error("数据添加失败！");
        }
    }

    /**
     * 更新数据
     *
     * @return 是否成功
     */
    @Override
    public AjaxResult updateTableData(PgRowInfo pgRowInfo) {
        boolean update = pgEditMapper.updateTableData(pgRowInfo.getTableName(), pgRowInfo.getId(), pgRowInfo.getNewRow(), pgRowInfo.getFields());
        if (update) {
            return AjaxResult.success("数据修改成功！");
        } else {
            return AjaxResult.error("数据修改失败！");
        }
    }

    /**
     * 删除数据
     *
     * @return 是否成功
     */
    @Override
    public AjaxResult deleteTableData(PgRowInfo pgRowInfo) {
        boolean del = pgEditMapper.deleteTableData(pgRowInfo.getTableName(), pgRowInfo.getId());
        if (del) {
            return AjaxResult.success("数据删除成功！");
        } else {
            return AjaxResult.error("数据删除失败！");
        }
    }

    @Override
    public AjaxResult addPointTableData(PgRowInfo pgRowInfo) {
        return this.addTableData(pgRowInfo);
    }

    @Override
    public AjaxResult updatePointTableData(PgRowInfo pgRowInfo) {
        return this.updateTableData(pgRowInfo);
    }

    @Override
    public AjaxResult addLineTableData(PgRowInfo pgRowInfo) {
        Map<String, Object> newRowMap = pgRowInfo.getNewRow();
        String pointTable = MapUtil.getStr(newRowMap, "pointTable"), sPoint = MapUtil.getStr(newRowMap, "S_POINT"), ePoint = MapUtil.getStr(newRowMap, "E_POINT"),
                geom = MapUtil.getStr(newRowMap, "geom"), road = MapUtil.getStr(newRowMap, "ROAD"), meteria = MapUtil.getStr(newRowMap, "MATERIAL"),
                sScode = MapUtil.getStr(newRowMap, "S_SCODE"), eScode = MapUtil.getStr(newRowMap, "E_SCODE");
        Integer sExist = MapUtil.getInt(newRowMap, "S_EXIST"), eExist = MapUtil.getInt(newRowMap, "E_EXIST");
        Double sDeep = MapUtil.getDouble(newRowMap, "S_DEEP"), eDeep = MapUtil.getDouble(newRowMap, "E_DEEP");
        String[] linePoints = geom.replace("MULTILINESTRING((", "").replace("))", "").split(",");

        String startPointCoordinate = linePoints[0], endPointCoordinate = linePoints[linePoints.length - 1];
        String[] startPointXY = startPointCoordinate.split(" "), endPointXY = endPointCoordinate.split(" ");
        boolean startPointAdded, endPointAdded;
        // 起点不存在
        if (sExist == 0) {
            Map<String, Object> startPointNewRow = new HashMap<>();

            startPointNewRow.put("geom", "POINT(" + startPointCoordinate + ")");
            startPointNewRow.put("EXP_NO", sPoint);
            startPointNewRow.put("SCODE", sScode);
            startPointNewRow.put("FEATURE", sScode);
            startPointNewRow.put("DEEP", sDeep);
            startPointNewRow.put("X", NumberUtil.parseDouble(startPointXY[0]));
            startPointNewRow.put("Y", NumberUtil.parseDouble(startPointXY[1]));
            startPointNewRow.put("H", 0);
            startPointNewRow.put("ROAD", road);
            startPointNewRow.put("METERIAL", meteria);
            startPointNewRow.put("transform_geom", "POINT(" + startPointCoordinate + ")");
            PgRowInfo startPoint = new PgRowInfo();
            startPoint.setTableName(pointTable);
            startPoint.setTableType(1);
            startPoint.setGeom("geom");
            startPoint.setFields(Arrays.asList("geom", "EXP_NO", "SCODE", "FEATURE", "DEEP", "X", "Y", "H", "ROAD", "METERIAL", "transform_geom"));
            startPoint.setNewRow(startPointNewRow);
            startPointAdded = pgEditMapper.insertTableData(startPoint.getTableName(), startPoint.getNewRow(), startPoint.getFields());
        } else {
            startPointAdded = true;
        }

        // 终点不存在
        if (eExist == 0) {
            Map<String, Object> endPointNewRow = new HashMap<>();
            endPointNewRow.put("geom", "POINT(" + endPointCoordinate + ")");
            endPointNewRow.put("EXP_NO", ePoint);
            endPointNewRow.put("SCODE", eScode);
            endPointNewRow.put("FEATURE", eScode);
            endPointNewRow.put("DEEP", eDeep);
            endPointNewRow.put("X", NumberUtil.parseDouble(endPointXY[0]));
            endPointNewRow.put("Y", NumberUtil.parseDouble(endPointXY[1]));
            endPointNewRow.put("H", 0);
            endPointNewRow.put("ROAD", road);
            endPointNewRow.put("METERIAL", meteria);
            endPointNewRow.put("transform_geom", "POINT(" + endPointCoordinate + ")");
            PgRowInfo endPoint = new PgRowInfo();
            endPoint.setTableName(pointTable);
            endPoint.setTableType(1);
            endPoint.setGeom("geom");
            endPoint.setFields(Arrays.asList("geom", "EXP_NO", "SCODE", "FEATURE", "DEEP", "X", "Y", "H", "ROAD", "METERIAL", "transform_geom"));
            endPoint.setNewRow(endPointNewRow);
            endPointAdded = pgEditMapper.insertTableData(endPoint.getTableName(), endPoint.getNewRow(), endPoint.getFields());
        } else {
            endPointAdded = true;
        }

        if (startPointAdded && endPointAdded) {
            pgRowInfo.setGeom("geom");
            pgRowInfo.getFields().remove("pointTable");
            pgRowInfo.getNewRow().remove("pointTable");
            pgRowInfo.getFields().remove("S_SCODE");
            pgRowInfo.getNewRow().remove("S_SCODE");
            pgRowInfo.getFields().remove("E_SCODE");
            pgRowInfo.getNewRow().remove("E_SCODE");
            pgRowInfo.getFields().remove("S_EXIST");
            pgRowInfo.getNewRow().remove("S_EXIST");
            pgRowInfo.getFields().remove("E_EXIST");
            pgRowInfo.getNewRow().remove("E_EXIST");
            return this.addTableData(pgRowInfo);
        }

        return AjaxResult.error("数据添加失败！");
    }

    @Override
    public AjaxResult updateLineTableData(PgRowInfo pgRowInfo) {
        pgRowInfo.getFields().remove("pointTable");
        pgRowInfo.getNewRow().remove("pointTable");
        return this.updateTableData(pgRowInfo);
    }

}
